package com.xxchat.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Objects;

import javax.annotation.Resource;

import com.xxchat.entity.constants.QueryConstants;
import com.xxchat.entity.constants.SysConstants;
import com.xxchat.entity.enums.ResponseCodeEnum;
import com.xxchat.entity.enums.SysVersionFileTypeEnum;
import com.xxchat.entity.enums.SysVersionStatusEnum;
import com.xxchat.exception.BusinessException;
import com.xxchat.utils.FileUploadUtils;
import org.springframework.stereotype.Service;

import com.xxchat.entity.enums.PageSize;
import com.xxchat.entity.query.SysVersionQuery;
import com.xxchat.entity.po.SysVersion;
import com.xxchat.entity.vo.PaginationResultVO;
import com.xxchat.entity.query.SimplePage;
import com.xxchat.mappers.SysVersionMapper;
import com.xxchat.service.SysVersionService;
import com.xxchat.utils.StringTools;
import org.springframework.web.multipart.MultipartFile;


/**
 * 版本发布 业务接口实现
 */
@Service("sysVersionService")
public class SysVersionServiceImpl implements SysVersionService {

	@Resource
	private SysVersionMapper<SysVersion, SysVersionQuery> sysVersionMapper;

	@Resource
	private FileUploadUtils fileUploadUtils;

	/**
	 * 根据条件查询列表
	 */
	@Override
	public List<SysVersion> findListByParam(SysVersionQuery param) {
		return this.sysVersionMapper.selectList(param);
	}

	/**
	 * 根据条件查询列表
	 */
	@Override
	public Integer findCountByParam(SysVersionQuery param) {
		return this.sysVersionMapper.selectCount(param);
	}

	/**
	 * 分页查询方法
	 */
	@Override
	public PaginationResultVO<SysVersion> findListByPage(SysVersionQuery param) {
		int count = this.findCountByParam(param);
		int pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();

		SimplePage page = new SimplePage(param.getPageNo(), count, pageSize);
		param.setSimplePage(page);
		List<SysVersion> list = this.findListByParam(param);
		PaginationResultVO<SysVersion> result = new PaginationResultVO(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);
		return result;
	}

	/**
	 * 新增
	 */
	@Override
	public Integer add(SysVersion bean) {
		return this.sysVersionMapper.insert(bean);
	}

	/**
	 * 批量新增
	 */
	@Override
	public Integer addBatch(List<SysVersion> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.sysVersionMapper.insertBatch(listBean);
	}

	/**
	 * 批量新增或者修改
	 */
	@Override
	public Integer addOrUpdateBatch(List<SysVersion> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.sysVersionMapper.insertOrUpdateBatch(listBean);
	}

	/**
	 * 多条件更新
	 */
	@Override
	public Integer updateByParam(SysVersion bean, SysVersionQuery param) {
		StringTools.checkParam(param);
		return this.sysVersionMapper.updateByParam(bean, param);
	}

	/**
	 * 多条件删除
	 */
	@Override
	public Integer deleteByParam(SysVersionQuery param) {
		StringTools.checkParam(param);
		return this.sysVersionMapper.deleteByParam(param);
	}

	/**
	 * 根据Id获取对象
	 */
	@Override
	public SysVersion getSysVersionById(Integer id) {
		return this.sysVersionMapper.selectById(id);
	}

	/**
	 * 根据Id修改
	 */
	@Override
	public Integer updateSysVersionById(SysVersion bean, Integer id) {
		return this.sysVersionMapper.updateById(bean, id);
	}

	/**
	 * 根据Id删除
	 */
	@Override
	public Integer deleteSysVersionById(Integer id) {
		return this.sysVersionMapper.deleteById(id);
	}

	@Override
	public void saveVersion(SysVersion sysVersion, MultipartFile file) {
		SysVersionFileTypeEnum type = SysVersionFileTypeEnum.getByType(sysVersion.getFileType());
		if (null == type) {
			throw new BusinessException(ResponseCodeEnum.CODE_600);
		}

		// 2. 校验外部链接和文件上传
		if (SysVersionFileTypeEnum.OUTER_LINK == type && StringTools.isEmpty(sysVersion.getOuterLink())) {
			throw new BusinessException(ResponseCodeEnum.CODE_502);
		}
		if (type == SysVersionFileTypeEnum.LOCAL && (null == file || file.isEmpty())) {
			throw new BusinessException(ResponseCodeEnum.CODE_503);
		}

		if (null == sysVersion.getId()) {
			// 如果是新增
			// 获取最新的版本，版本对比
			SysVersionQuery query = new SysVersionQuery();
			query.setOrderBy(QueryConstants.ORDER_BY_ID_DESC);
			query.setSimplePage(new SimplePage(0, 1));
			List<SysVersion> sysVersions = this.sysVersionMapper.selectList(query);
			if (null != sysVersions && !sysVersions.isEmpty()) {
				SysVersion latestVersion = sysVersions.get(0);
				if (!isVersionGreater(sysVersion.getVersion(), latestVersion.getVersion())) {
					throw new BusinessException(ResponseCodeEnum.CODE_501);
				}
			}
			sysVersion.setCreateTime(new Date());
			sysVersion.setStatus(SysVersionStatusEnum.INIT.getStatus());
			this.sysVersionMapper.insert(sysVersion);
		} else {
			// 如果是修改
			SysVersion dbVersion = this.sysVersionMapper.selectById(sysVersion.getId());
			if (null == dbVersion ||
					!SysVersionStatusEnum.INIT.getStatus().equals(dbVersion.getStatus()) ||
                    !Objects.equals(dbVersion.getVersion(), sysVersion.getVersion())
			) {
				// 没查到或者状态已经是发布的或者修改了版本号的，不给修改
				throw new BusinessException(ResponseCodeEnum.CODE_600);
			}

			this.sysVersionMapper.updateById(sysVersion, sysVersion.getId());
		}

		if (null != file) {
			String fileName = sysVersion.getVersion() + SysConstants.VERSION_EXE_SUFFIX;
			fileUploadUtils.handleVersionFile(fileName, file);
		}
	}

	/**
	 * 比较版本号大小
	 * @param newVersion 新版本号
	 * @param oldVersion 旧版本号
	 * @return true-新版本号大于旧版本号
	 */
	private boolean isVersionGreater(String newVersion, String oldVersion) {
		String[] newParts = newVersion.split("\\.");
		String[] oldParts = oldVersion.split("\\.");

		for (int i = 0; i < Math.max(newParts.length, oldParts.length); i++) {
			int newPart = i < newParts.length ? Integer.parseInt(newParts[i]) : 0;
			int oldPart = i < oldParts.length ? Integer.parseInt(oldParts[i]) : 0;

			if (newPart > oldPart) {
				return true;
			} else if (newPart < oldPart) {
				return false;
			}
		}
		return false;
	}

	@Override
	public void postVersion(Integer id, Integer status, String grayScaleUid) {
		SysVersionStatusEnum statusEnum = SysVersionStatusEnum.getByStatus(status);
		if (null == statusEnum) {
			throw new BusinessException(ResponseCodeEnum.CODE_600);
		}
		if (SysVersionStatusEnum.GRAYSCALE.equals(statusEnum) && StringTools.isEmpty(grayScaleUid)) {
			throw new BusinessException(ResponseCodeEnum.CODE_600);
		}
		if (!SysVersionStatusEnum.GRAYSCALE.equals(statusEnum)) {
			grayScaleUid = "";
		}
		// TODO 外链
		SysVersion version = new SysVersion();
		version.setStatus(statusEnum.getStatus());
		version.setGrayscaleUid(grayScaleUid);
		this.sysVersionMapper.updateById(version, id);
	}

	@Override
	public SysVersion checkVersion(String version, String uid) {
		SysVersion sysVersion = this.sysVersionMapper.selectLatestVersion(uid);
		if (null == sysVersion || sysVersion.getVersion().equals(version)) {
			return null;
		}
		return sysVersion;
	}
}